home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 366_01 / ue311c1.arc / EXEC.C < prev   
C/C++ Source or Header  |  1991-10-10  |  33KB  |  1,489 lines

  1. /*    This file is for functions dealing with execution of
  2.     commands, command lines, buffers, files and startup files
  3.  
  4.     written 1986 by Daniel Lawrence                */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "eproto.h"
  9. #include    "edef.h"
  10. #include    "elang.h"
  11.  
  12. /* namedcmd:    execute a named command even if it is not bound */
  13.  
  14. PASCAL NEAR namedcmd(f, n)
  15.  
  16. int f, n;    /* command arguments [passed through to command executed] */
  17.  
  18. {
  19.     int (PASCAL NEAR *kfunc)();     /* ptr to the function to execute */
  20.     char buffer[NSTRING];        /* buffer to store function name */
  21.     int status;
  22.  
  23.     /* if we are non-interactive.... force the command interactivly */
  24.     if (clexec == TRUE) {
  25.         /* grab token and advance past */
  26.         execstr = token(execstr, buffer, NPAT);
  27.  
  28.         /* evaluate it */
  29.         strcpy(buffer, fixnull(getval(buffer)));
  30.         if (strcmp(buffer, errorm) == 0)
  31.             return(FALSE);
  32.  
  33.         /* and look it up */
  34.         if ((kfunc = fncmatch(buffer)) == NULL) {
  35.             mlwrite(TEXT16);
  36. /*                          "[No such Function]" */
  37.             return(FALSE);
  38.         }
  39.         
  40.         /* and execute it  INTERACTIVE */
  41.         clexec = FALSE;
  42.         status = (*kfunc)(f, n);    /* call the function */
  43.         clexec = TRUE;
  44.         return(status);
  45.     }
  46.  
  47.     /* prompt the user to type a named command */
  48.     /* and get the function name to execute */
  49.     kfunc = getname(": ");
  50.     if (kfunc == NULL) {
  51.         mlwrite(TEXT16);
  52. /*                      "[No such function]" */
  53.         return(FALSE);
  54.     }
  55.  
  56.     /* and then execute the command */
  57.     return((*kfunc)(f, n));
  58. }
  59.  
  60. /*    execcmd:    Execute a command line command to be typed in
  61.             by the user                    */
  62.  
  63. PASCAL NEAR execcmd(f, n)
  64.  
  65. int f, n;    /* default Flag and Numeric argument */
  66.  
  67. {
  68.     register int status;        /* status return */
  69.     char cmdstr[NSTRING];        /* string holding command to execute */
  70.  
  71.     /* get the line wanted */
  72.     if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE)
  73.         return(status);
  74.  
  75.     execlevel = 0;
  76.     return(docmd(cmdstr));
  77. }
  78.  
  79. /*    docmd:    take a passed string as a command line and translate
  80.         it to be executed as a command. This function will be
  81.         used by execute-command-line and by all source and
  82.         startup files. Lastflag/thisflag is also updated.
  83.  
  84.     format of the command line is:
  85.  
  86.         {# arg} <command-name> {<argument string(s)>}
  87.  
  88. */
  89.  
  90. PASCAL NEAR docmd(cline)
  91.  
  92. char *cline;    /* command line to execute */
  93.  
  94. {
  95.     register int f;        /* default argument flag */
  96.     register int n;        /* numeric repeat value */
  97.     int (PASCAL NEAR *fnc)();/* function to execute */
  98.     BUFFER *bp;        /* buffer to execute */
  99.     int status;        /* return status of function */
  100.     int oldcle;        /* old contents of clexec flag */
  101.     char *oldestr;        /* original exec string */
  102.     char tkn[NSTRING];    /* next token off of command line */
  103.         char bufn[NBUFN+2];    /* name of buffer to execute */
  104.  
  105.     /* if we are scanning and not executing..go back here */
  106.     if (execlevel)
  107.         return(TRUE);
  108.  
  109.     oldestr = execstr;    /* save last ptr to string to execute */
  110.     execstr = cline;    /* and set this one as current */
  111.  
  112.     /* first set up the default command values */
  113.     f = FALSE;
  114.     n = 1;
  115.     lastflag = thisflag;
  116.     thisflag = 0;
  117.  
  118.     if ((status = macarg(tkn)) != TRUE) {    /* and grab the first token */
  119.         execstr = oldestr;
  120.         return(status);
  121.     }
  122.  
  123.     /* process leadin argument */
  124.     if (gettyp(tkn) != TKCMD) {
  125.         f = TRUE;
  126.         strcpy(tkn, fixnull(getval(tkn)));
  127.         n = asc_int(tkn);
  128.  
  129.         /* and now get the command to execute */
  130.         if ((status = macarg(tkn)) != TRUE) {
  131.             execstr = oldestr;
  132.             return(status);
  133.         }
  134.     }
  135.  
  136.     /* and match the token to see if it exists */
  137.     if ((fnc = fncmatch(tkn)) == NULL) {
  138.  
  139.         /* construct the buffer name */
  140.         strcpy(bufn, "[");
  141.         strcat(bufn, tkn);
  142.         strcat(bufn, "]");
  143.  
  144.         /* find the pointer to that buffer */
  145.             if ((bp=bfind(bufn, FALSE, 0)) == NULL) {
  146.             mlwrite(TEXT16);
  147. /*                          "[No such Function]" */
  148.             execstr = oldestr;
  149.             return(FALSE);
  150.         }
  151.  
  152.         /* execute the buffer */
  153.         oldcle = clexec;    /* save old clexec flag */
  154.         clexec = TRUE;        /* in cline execution */
  155.         while (n-- > 0)
  156.             if ((status = dobuf(bp)) != TRUE)
  157.                 break;
  158.         cmdstatus = status;    /* save the status */
  159.         clexec = oldcle;    /* restore clexec flag */
  160.         execstr = oldestr;
  161.         return(status);
  162.     }
  163.     
  164.     /* save the arguments and go execute the command */
  165.     oldcle = clexec;        /* save old clexec flag */
  166.     clexec = TRUE;            /* in cline execution */
  167.     status = (*fnc)(f, n);        /* call the function */
  168.     cmdstatus = status;        /* save the status */
  169.     clexec = oldcle;        /* restore clexec flag */
  170.     execstr = oldestr;
  171.     return(status);
  172. }
  173.  
  174. /* token:    chop a token off a string
  175.         return a pointer past the token
  176. */
  177.  
  178. char *PASCAL NEAR token(src, tok, size)
  179.  
  180. char *src, *tok;    /* source string, destination token string */
  181. int size;        /* maximum size of token */
  182.  
  183. {
  184.     register int quotef;    /* is the current string quoted? */
  185.     register char c;    /* temporary character */
  186.  
  187.     /* first scan past any whitespace in the source string */
  188.     while (*src == ' ' || *src == '\t')
  189.         ++src;
  190.  
  191.     /* scan through the source string */
  192.     quotef = FALSE;
  193.     while (*src) {
  194.         /* process special characters */
  195.         if (*src == '~') {
  196.             ++src;
  197.             if (*src == 0)
  198.                 break;
  199.             switch (*src++) {
  200.                 case 'r':    c = 13; break;
  201.                 case 'n':    c = 13; break;
  202.                 case 'l':    c = 10; break;
  203.                 case 't':    c = 9;  break;
  204.                 case 'b':    c = 8;  break;
  205.                 case 'f':    c = 12; break;
  206.                 default:    c = *(src-1);
  207.             }
  208.             if (--size > 0) {
  209.                 *tok++ = c;
  210.             }
  211.         } else {
  212.             /* check for the end of the token */
  213.             if (quotef) {
  214.                 if (*src == '"')
  215.                     break;
  216.             } else {
  217.                 if (*src == ' ' || *src == '\t')
  218.                     break;
  219.             }
  220.  
  221.             /* set quote mode if quote found */
  222.             if (*src == '"')
  223.                 quotef = TRUE;
  224.  
  225.             /* record the character */
  226.             c = *src++;
  227.             if (--size > 0)
  228.                 *tok++ = c;
  229.         }
  230.     }
  231.  
  232.     /* terminate the token and exit */
  233.     if (*src)
  234.         ++src;
  235.     *tok = 0;
  236.     return(src);
  237. }
  238.  
  239. PASCAL NEAR macarg(tok)    /* get a macro line argument */
  240.  
  241. char *tok;    /* buffer to place argument */
  242.  
  243. {
  244.     int savcle;    /* buffer to store original clexec */
  245.     int status;
  246.  
  247.     savcle = clexec;    /* save execution mode */
  248.     clexec = TRUE;        /* get the argument */
  249.     status = nextarg("", tok, NSTRING, ctoec('\r'));
  250.     clexec = savcle;    /* restore execution mode */
  251.     return(status);
  252. }
  253.  
  254. /*    nextarg:    get the next argument    */
  255.  
  256. PASCAL NEAR nextarg(prompt, buffer, size, terminator)
  257.  
  258. char *prompt;        /* prompt to use if we must be interactive */
  259. char *buffer;        /* buffer to put token into */
  260. int size;        /* size of the buffer */
  261. int terminator;        /* terminating char to be used on interactive fetch */
  262.  
  263. {
  264.     register char *sp;    /* return pointer from getval() */
  265.  
  266.     /* if we are interactive, go get it! */
  267.     if (clexec == FALSE)
  268.         return(getstring(prompt, buffer, size, terminator));
  269.  
  270.     /* grab token and advance past */
  271.     execstr = token(execstr, buffer, size);
  272.  
  273.     /* evaluate it */
  274.     if ((sp = getval(buffer)) == NULL)
  275.         return(FALSE);
  276.     strcpy(buffer, sp);
  277.     return(TRUE);
  278. }
  279.  
  280. /*    storemac:    Set up a macro buffer and flag to store all
  281.             executed command lines there            */
  282.  
  283. PASCAL NEAR storemac(f, n)
  284.  
  285. int f;        /* default flag */
  286. int n;        /* macro number to use */
  287.  
  288. {
  289.     register struct BUFFER *bp;    /* pointer to macro buffer */
  290.     char bname[NBUFN];        /* name of buffer to use */
  291.  
  292.     /* must have a numeric argument to this function */
  293.     if (f == FALSE) {
  294.         mlwrite(TEXT111);
  295. /*                      "No macro specified" */
  296.         return(FALSE);
  297.     }
  298.  
  299.     /* range check the macro number */
  300.     if (n < 1 || n > 40) {
  301.         mlwrite(TEXT112);
  302. /*                      "Macro number out of range" */
  303.         return(FALSE);
  304.     }
  305.  
  306.     /* construct the macro buffer name */
  307.     strcpy(bname, "[Macro xx]");
  308.     bname[7] = '0' + (n / 10);
  309.     bname[8] = '0' + (n % 10);
  310.  
  311.     /* set up the new macro buffer */
  312.     if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) {
  313.         mlwrite(TEXT113);
  314. /*                      "Can not create macro" */
  315.         return(FALSE);
  316.     }
  317.  
  318.     /* and make sure it is empty */
  319.     bclear(bp);
  320.  
  321.     /* and set the macro store pointers to it */
  322.     mstore = TRUE;
  323.     bstore = bp;
  324.     return(TRUE);
  325. }
  326.  
  327. /*    storeproc:    Set up a procedure buffer and flag to store all
  328.             executed command lines there            */